﻿using System;
using System.ComponentModel;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Imperium
{
    class ImperiumModel : INotifyPropertyChanged
    {
        #region INotify

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region ModelProperties

        private string _ip;
        public String IP
        {
            get
            {
                return _ip;
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("IP Address cannot be empty");
                }

                _ip = value;
                Properties.Settings.Default.IpAddress = _ip;
                Properties.Settings.Default.Save();
                OnPropertyChanged("IP");
            }
        }

        private int _port;
        public int Port
        {
            get
            {
                return _port;
            }

            set
            {
                if (String.IsNullOrEmpty(value.ToString()))
                {
                    throw new ArgumentException("Port cannot be empty");
                }

                _port = value;
                Properties.Settings.Default.Port = _port;
                Properties.Settings.Default.Save();
                OnPropertyChanged("Port");
            }
        }

        private String _user;
        public String User
        {
            get
            {
                return _user;
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("User cannot be empty");
                }

                _user = value;
                Properties.Settings.Default.Username = _user;
                Properties.Settings.Default.Save();
                OnPropertyChanged("User");
            }
        }

        private String _password;
        public String Password
        {
            get
            {
                return _password;
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("Password cannot be empty");
                }

                _password = value;
                Properties.Settings.Default.Password = _password;
                Properties.Settings.Default.Save();
                OnPropertyChanged("Password");
            }
        }

        private String _name;
        public String Name
        {
            get
            {
                return _name;
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("Name cannot be empty");
                }

                _name = value;
                Properties.Settings.Default.Name = _name;
                Properties.Settings.Default.Save();
                OnPropertyChanged("Name");
            }
        }

        private String _speechHeard;
        public String SpeechHeard
        {
            get
            {
                return _speechHeard;
            }

            set
            {
                _speechHeard = value;
                OnPropertyChanged("SpeechHeard");
            }
        }

        private float _confidence;
        public float Confidence
        {
            get
            {
                return _confidence;
            }

            set
            {
                _confidence = value;
                OnPropertyChanged("Confidence");
            }
        }

        private String _kinectState;
        public String KinectState
        {
            get
            {
                return _kinectState;
            }

            set
            {
                _kinectState = value;
                OnPropertyChanged("KinectState");
            }
        }

        private String _xbmcState;
        public String XbmcState
        {
            get
            {
                return _xbmcState;
            }

            set
            {
                _xbmcState = value;
                OnPropertyChanged("XbmcState");
            }
        }

        private ImageSource _imageSource;
        public ImageSource ImageSource
        {
            get
            {
                return _imageSource;
            }

            set
            {
                _imageSource = value;
                OnPropertyChanged("ImageSource");
            }
        }

        #endregion

        private ImperiumController controller;
        public Uri uriLogo = new Uri("../Images/Imperium_Logo_Gray.png", UriKind.Relative);
        public Uri uriBrightLogo = new Uri("../Images/Imperium_Logo_White.png", UriKind.Relative);

        /// <summary>
        /// Constructor for ImperiumModel
        /// </summary>
        public ImperiumModel()
        {
            Init();
            
            SetImperiumLogo(false);

            SetupController();
        }

        private void Init()
        {
            this.IP = Properties.Settings.Default.IpAddress;
            this.Name = Properties.Settings.Default.Name;
            this.Password = Properties.Settings.Default.Password;
            this.Port = Properties.Settings.Default.Port;
            this.User = Properties.Settings.Default.Username;
        }

        /// <summary>
        /// Callback to set the Imperium logo
        /// </summary>
        public void SetImperiumLogo(bool bright)
        {
            if (bright)
                this.ImageSource = new BitmapImage(this.uriBrightLogo);
            else
                this.ImageSource = new BitmapImage(this.uriLogo);
        }

        private void SetupController()
        {
            this.controller = new ImperiumController(this);
        }

        public void CommandGiven(String Command, float Confidence)
        {
#if DEBUG
            {
                this.SpeechHeard = Command;
                this.Confidence = Confidence;
            }
#endif
            controller.CommandGiven(Command, Confidence);
        }

        /// <summary>
        /// Test connection to XBMC
        /// </summary>
        public void TestXBMC()
        {
            this.XbmcState = ImperiumController.TestConnection();
        }

        public void ConnectKinect()
        {
            this.controller.SetupKinect();
        }
    }
}
